package com.outsourcing.bottle.util;

import java.io.File;
import java.io.FileOutputStream;
import java.lang.Thread.UncaughtExceptionHandler;
import java.text.SimpleDateFormat;
import java.util.Date;

import android.content.Context;
import android.os.Looper;
import android.util.Log;
import android.widget.Toast;

import com.android.ShellCommand;
import com.android.ShellCommand.CommandResult;
import com.outsourcing.bottle.R;

/**
 * 
 * @author 06peng
 * 
 */
public class CrashHandler implements UncaughtExceptionHandler {
	/** Debug Log tag */
	public static final String TAG = "CrashHandler";
	/**
	 * 是否开启日志输出,在Debug状态下开启, 在Release状态下关闭以提示程序性能
	 * */
	public static final boolean DEBUG = true;
	/** 系统默认的UncaughtException处理类 */
	private Thread.UncaughtExceptionHandler mDefaultHandler;
	/** CrashHandler实例 */
	private static CrashHandler INSTANCE;
	/** 程序的Context对象 */
	private Context mContext;

	/** 保证只有一个CrashHandler实例 */
	private CrashHandler() {
	}

	public static final String UPLOADED = "uploaded";// 已上传

	/** 获取CrashHandler实例 ,单例模式 */
	public static CrashHandler getInstance() {
		if (INSTANCE == null) {
			INSTANCE = new CrashHandler();
		}
		return INSTANCE;
	}

	/**
	 * 初始化,注册Context对象, 获取系统默认的UncaughtException处理器, 设置该CrashHandler为程序的默认处理器
	 * 
	 * @param ctx
	 */
	public void init(Context ctx) {
		mContext = ctx;
		mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
		Thread.setDefaultUncaughtExceptionHandler(this);
	}

	/**
	 * 当UncaughtException发生时会转入该函数来处理
	 */
	@Override
	public void uncaughtException(Thread thread, Throwable ex) {
		if (!handleException(ex) && mDefaultHandler != null) {
			// 如果用户没有处理则让系统默认的异常处理器来处理
			mDefaultHandler.uncaughtException(thread, ex);
		} else {
			// Sleep一会后结束程序
			try {
				Thread.sleep(2000);

			} catch (InterruptedException e) {
				Log.e(TAG, "Error : ", e);
			}
			ActivityManager.finishAll();
			android.os.Process.killProcess(android.os.Process.myPid());
			System.exit(10);
		}
	}

	/**
	 * 自定义错误处理,收集错误信息 发送错误报告等操作均在此完成. 开发者可以根据自己的情况来自定义异常处理逻辑
	 * 
	 * @param ex
	 * @return true:如果处理了该异常信息;否则返回false
	 */
	private boolean handleException(Throwable ex) {
		if (ex == null) {
			return true;
		}
		// 使用Toast来显示异常信息
		new Thread() {
			@Override
			public void run() {
				Looper.prepare();
				Toast.makeText(mContext, mContext.getString(R.string.system_error), Toast.LENGTH_LONG).show();
				Looper.loop();
			}
		}.start();
		// 保存错误报告文件
		ex.printStackTrace();
		saveCrashInfoToFile();
		return true;
	}

	/**
	 * 保存错误报告文件
	 */
	public void saveCrashInfoToFile() {
		try {
			File file = new File(android.os.Environment
					.getExternalStorageDirectory().getPath() + "/" + AppContext.SD_PATH + "/crashlog/");
			if (!file.exists()) {
				file.mkdirs();
			}
			file = null;
		} catch (Exception e) {
			e.printStackTrace();
		}
		ShellCommand sc = new ShellCommand();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
		Date curDate = new Date(System.currentTimeMillis());
		String str = formatter.format(curDate);
		CommandResult cr = sc.normal.runWaitFor("logcat -d *:W/System.err >> " + str + ".txt");
		System.out.println("command result>>>" + cr.exit_value);
		if (cr.success()) {
			try {
				File file = new File(android.os.Environment.getExternalStorageDirectory().getPath()
						 + "/" + AppContext.SD_PATH + "/crashlog/" + str + ".txt");
				if (!file.exists())
					file.createNewFile();
				FileOutputStream fos = new FileOutputStream(file);
				fos.write(("T3;" + new SimpleDateFormat("yyyyMMddHHmm").format(System.currentTimeMillis()) + ';'
						+ AppContext.getInstance().getLogin_uid() + "/" + str + ":" + cr.stdout).getBytes());
				fos.flush();
				fos.close();
				file = null;
			} catch (Exception ex) {
				ex.printStackTrace();
			}
		}
	}
}